package com.cysyz.web.modules.base.support.service;


import com.cysyz.mylib.dao.BaseDao;
import com.cysyz.mylib.dao.Conds;
import com.cysyz.mylib.dao.PagingResult;
import com.cysyz.mylib.dao.engine.ClassMetadata;
import com.cysyz.mylib.dao.engine.PersistenceEngine;
import com.cysyz.mylib.dao.engine.Query;
import com.cysyz.mylib.dao.impl.ClassAndIdPropetryName;
import com.cysyz.mylib.dao.type.Type;
import com.cysyz.mylib.datacopytool.DataCopyTool;
import com.cysyz.mylib.datacopytool.SimpleDataCopyTool;
import com.cysyz.mylib.domain.identifier.Identifiable;
import com.cysyz.mylib.utils.myassert.MyAssert;
import com.cysyz.web.modules.base.support.ServletActionContext;
import com.cysyz.web.modules.base.support.SysConstants;

import javax.annotation.Resource;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * Created by jiaoyujia on 2015/1/6.
 */
public class BaseService {
    @Resource
    BaseDao baseDao;

    public void save(Object entity) {
        baseDao.save(entity);
    }

    public <T> PagingResult<T> listPaging(String sql, List<Object> params, Class<T> clazz, int page, int maxresult) {
        return baseDao.listPaging(sql, params, clazz, page, maxresult);
    }

    public Object getSingleResult(String ql, Map<String, Object> paramPlaceAndValues) {
        return baseDao.getSingleResult(ql, paramPlaceAndValues);
    }

    public <T> PagingResult<T> listPagingEntity(String sql, List<Object> params, Class<T> clazz, Map<String, Type> scalars, int page, int maxresult) {
        return baseDao.listPagingEntity(sql, params, clazz, scalars, page, maxresult);
    }

    public PersistenceEngine getPersistenceEngine() {
        return baseDao.getPersistenceEngine();
    }

    public int execute(String ql, List<Object> params) {
        return baseDao.execute(ql, params);
    }

    public <T> List<T> listCacheAble(Class<T> clazz) {
        return baseDao.listCacheAble(clazz);
    }

    public <T> T load(Class<T> clazz, Serializable entityID) {
        return baseDao.load(clazz, entityID);
    }

    public <T> long getCount(Class<T> clazz, Conds conds, String queryPostfix) {
        return baseDao.getCount(clazz, conds, queryPostfix);
    }

    public <T> List<T> list(Class<T> clazz, String queryPrefix, String queryPostfix) {
        return baseDao.list(clazz, queryPrefix, queryPostfix);
    }

    public void setPersistenceEngine(PersistenceEngine persistenceEngine) {
        baseDao.setPersistenceEngine(persistenceEngine);
    }

    public <T> List<T> listCacheAble(Class<T> clazz, String[] fieldNames, Conds conds) {
        return baseDao.listCacheAble(clazz, fieldNames, conds);
    }

    public <T> List<T> list(String sql, List<Object> params, Class<T> clazz) {
        return baseDao.list(sql, params, clazz);
    }

    public <T> PagingResult<T> listPaging(Class<T> clazz, int page, int maxresult) {
        return baseDao.listPaging(clazz, page, maxresult);
    }

    public <T extends Object> T get(Class<T> clazz, Serializable id) {
        return baseDao.get(clazz, id);
    }

    public <T> List<T> list(Class<T> clazz, Conds conds) {
        return baseDao.list(clazz, conds);
    }

    public <T> List<T> list(Class<T> clazz, boolean isDistinct, String[] fieldNames, Conds conds) {
        return baseDao.list(clazz, isDistinct, fieldNames, conds);
    }

    public void removeByCollection(List list) {
        baseDao.removeByCollection(list);
    }

    public <T> long getCount(Class<T> clazz, Conds conds) {
        return baseDao.getCount(clazz, conds);
    }

    public <T> List<T> listCacheAble(Class<T> clazz, Conds conds) {
        return baseDao.listCacheAble(clazz, conds);
    }

    public <T> void remove(Class<T> clazz, Serializable entityID) {
        baseDao.remove(clazz, entityID);
    }

    public int executeSql(String sql, List<Object> params) {
        return baseDao.executeSql(sql, params);
    }

    public <T> PagingResult<T> listPaging(Class<T> clazz, Conds conds, String queryPrefix, String queryPostfix, int page, int maxresult) {
        return baseDao.listPaging(clazz, conds, queryPrefix, queryPostfix, page, maxresult);
    }

    public <T> List<T> listCacheAble(Class<T> clazz, boolean isDistinct, String[] fieldNames, Conds conds) {
        return baseDao.listCacheAble(clazz, isDistinct, fieldNames, conds);
    }

    public <T> PagingResult<T> listPaging(Class<T> clazz, String queryPrefix, String queryPostfix, int page, int maxresult) {
        return baseDao.listPaging(clazz, queryPrefix, queryPostfix, page, maxresult);
    }

    public <T> List<T> list(Class<T> clazz, boolean isDistinct, String[] fieldNames) {
        return baseDao.list(clazz, isDistinct, fieldNames);
    }

    public <T> List<T> list(Class<T> clazz, String[] fieldNames, Conds conds) {
        return baseDao.list(clazz, fieldNames, conds);
    }

    public <T, M, N extends Object> void m2MRelationshipMapping(Class<T> manyClazz1, Serializable manyClass1Id, Class<M> manyClass2, List<? extends Serializable> manyKeyList, Class<N> middleClass) {
        if (manyClass1Id != null && (manyKeyList != null && !manyKeyList.isEmpty())) {
            if (!(manyKeyList.get(0) instanceof Long)) {
                List<Long> longElementsList = new ArrayList<>();
                for (Serializable serializable : manyKeyList) {
                    longElementsList.add(Long.parseLong((String) serializable));
                }
                manyKeyList = longElementsList;
            }
        }
        baseDao.m2MRelationshipMapping(
                new ClassAndIdPropetryName<T>(manyClazz1, "id"),
                manyClass1Id,
                new ClassAndIdPropetryName<M>(manyClass2, "id"),
                manyKeyList,
                middleClass);
    }

    public <T> long getCount(Class<T> clazz, Conds conds, Query queryForData) {
        return baseDao.getCount(clazz, conds, queryForData);
    }


    public <T> PagingResult<T> listPaging(String sql, List<Object> params, Class<T> clazz, Map<String, Type> scalars, int page, int maxresult) {
        return baseDao.listPaging(sql, params, clazz, scalars, page, maxresult);
    }

    public <T> PagingResult<T> listPaging(String sql, Class<T> clazz, Map<String, Type> scalars, int page, int maxresult) {
        return baseDao.listPaging(sql, clazz, scalars, page, maxresult);
    }

    public <T> List<T> list(Class<T> clazz) {
        return baseDao.list(clazz);
    }

    public <T extends Identifiable>void merge(Class<T> clazz, T entity, String... fieldNames) {
        T entityRep = this.get(clazz, entity.getId());
        MyAssert.notNull(entityRep);

        DataCopyTool dataCopyTool = new SimpleDataCopyTool();
        dataCopyTool.copyValues(entity, entityRep, fieldNames);
        baseDao.merge(entityRep);
    }

    public <T> long getCount(Class<T> clazz) {
        return baseDao.getCount(clazz);
    }

    public <T> List<T> list(Class<T> clazz, String queryPrefix) {
        return baseDao.list(clazz, queryPrefix);
    }

    public <T> List<T> list(String sql, List<Object> params, Class<T> clazz, Map<String, Type> scalars) {
        return baseDao.list(sql, params, clazz, scalars);
    }

    public <T> PagingResult<T> listPaging(Class<T> clazz, Conds conds, int page, int maxresult) {
        return baseDao.listPaging(clazz, conds, page, maxresult);
    }

    public ClassMetadata getClassMetaData(Class clazz) {
        return baseDao.getClassMetaData(clazz);
    }

    protected void setBusineeLogMessage(String msg) {
        ServletActionContext.getContext().put(SysConstants.BusinessLog.BUSINESSLOG_MESSAGE, msg);
    }

    public Object getSingleResult(String sql, List<Object> params) {
        return baseDao.getSingleResult(sql, params);
    }
}
